# -*- coding: utf-8 -*-

import cv2
import numpy as np
from car_detector.detector import car_detector, bow_features
from car_detector.pyramid import pyramid
from car_detector.non_maximum import non_max_suppression_fast as nms
from car_detector.sliding_window import sliding_window
#import urllib

def in_range(number, test, thresh=0.2):
    #返回0或1
    return abs(number - test) < thresh

#test_image = "/home/d3athmast3r/dev/python/pycv/images/cars.jpg"
img_path = "test_images/cars.jpg"

#urllib.request.urlretrieve(test_image, img_path) #导入图像，估计没用
#urllib.request.urlretrieve(img_path)

svm, extractor = car_detector() #开始训练
detect = cv2.xfeatures2d.SIFT_create()

w, h = 100, 40 #限制滑窗尺寸
img = cv2.imread(img_path,cv2.IMREAD_REDUCED_COLOR_4)
#img = cv2.imread(test_image)

rectangles = []
counter = 1
scaleFactor = 1.25
scale = 1
font = cv2.FONT_HERSHEY_PLAIN

'''开始滑窗寻找目标'''
for resized in pyramid(img, scaleFactor):  
    scale = float(img.shape[1]) / float(resized.shape[1])
    for (x, y, roi) in sliding_window(resized, 20, (100, 40)): #按(100, 40)尺寸把图片切割成新的图片 #注意要修改改尺寸也要同步修改w,h
    
        if roi.shape[1] != w or roi.shape[0] != h:
		#不满足尺寸的小区域图片就舍去不要
            continue

        try:
            #最重要部分代码
            bf = bow_features(roi, extractor, detect)
            _, result = svm.predict(bf)
            a, res = svm.predict(bf, flags=cv2.ml.STAT_MODEL_RAW_OUTPUT | cv2.ml.STAT_MODEL_UPDATE_MODEL)
            print("Class: %d, Score: %f, a: %s" % (result[0][0], res[0][0], res))
            score = res[0][0]
            if result[0][0] == 1:
                if score < -1.0:
                    #修改矩形框的尺寸
                    rx, ry, rx2, ry2 = int(x * scale), int(y * scale), int((x+w) * scale), int((y+h) * scale)
                    rectangles.append([rx, ry, rx2, ry2, abs(score)])
        except:
            pass
        counter += 1 

windows = np.array(rectangles) # 修改矩形框的类型
boxes = nms(windows, 0.25)     # 非极大值抑制处理


for (x, y, x2, y2, score) in boxes:
    print(x, y, x2, y2, score)
    cv2.rectangle(img, (int(x),int(y)),(int(x2), int(y2)),(0, 255, 0), 1) #画出矩形框
    cv2.putText(img, "%f" % score, (int(x),int(y)), font, 1, (0, 255, 0)) #在图像上输出坐标

cv2.imshow("img", img)
cv2.waitKey(0)


"""
常报的错：
1、'NoneType' object has no attribute 'shape'
    原因：读取的图片地址写错
2、error: (-215) !_descriptors.empty() in function cv::BOWTrainer::add
    原因：读取的图片地址出错，要注意所用到的所有自己编写的文件上的地址，尤其带中文跟特殊字符的，经常出错
"""


